package org.qiuer.ast.expression.function;

import org.qiuer.ast.INode;
import org.qiuer.ast.assign.AssignKind;
import org.qiuer.ast.expression.Expression;
import org.qiuer.ast.expression.IExpression;
import org.qiuer.ast.expression.Identifier;
import org.qiuer.ast.pattern.IPattern;
import org.qiuer.run.Context;
import org.qiuer.run.FunctionRegistrar;
import org.qiuer.exception.Const;
import org.qiuer.exception.ERuntime;
import org.qiuer.exception.IException;

import java.util.ArrayList;
import java.util.List;

// 不需要这个。
@Deprecated
public abstract class Function extends Expression{
  public String type = "Function";
  public Identifier id;
  public List<IPattern> params = new ArrayList<>();
  public List<IExpression> defaults = new ArrayList<>(); // TODO 函数给默认值。未实现。
  public Identifier rest;
  public INode body; // BlockStatement || Expression
  public boolean generator;
  public boolean expression;


  @Override
  public Object run(Context context) throws IException {
    throw new ERuntime(Const.EXCEPTION.UNSUPPORTED_OPERATION, "框架错误：调用函数请使用带参数的run方法");
  }

  public Object run(Context context, List<IExpression> arguments) throws IException {
    Object[] args = FunctionRegistrar.prepareParams(context, arguments);
    return this.run(context, args);
  }

  public Object run(Context context, Object... args) throws IException {
    context.enterScope();
    Object ret;
    try {
      int size = params.size();
      for (int i = 0; i < size; i++) {
        IPattern param = this.params.get(i);
        if (param instanceof Identifier) {
          context.declareVariable(((Identifier) param).name, args[i], AssignKind.LET);
        } else {
          throw new ERuntime(Const.EXCEPTION.UNKNOWN_ERROR, "函数: " + id.name + "定义的参数名称只能是简单的标识符Identifier");
        }
      }
      ret = body.run(context);
      return ret;
    }finally {
      context.exitScope();
    }
  }
}